package processing_model;

import processing.core.PApplet;
import processing.core.PImage;

public class Display3D extends PApplet {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private PImage img_floor1;
	private PImage img_floor2;
	private PImage img_temp;
	private float rotx = -PI / 4;
	private float roty = 0;
	private float scale = 1;
	private int currentFloorIndex = 2;
	private float changeFloorCount = 0;
	private final float MAX_CHANGE_FLOOR_COUNT = 45;
	private float transparent_floor1;
	private float transparent_floor2;
	private final int FLOOR_WIDTH = 200;
	public void setup() {
		size(1350, 580, P3D);
		img_floor1 = loadImage("./images/dst_floor1.png");
		img_floor2 = loadImage("./images/dst_floor0.png");
	}

	public void draw() {
		colorMode(RGB, 255);
		background(0);
		translate(width / 2, height / 3);
		rotateX(rotx);
		rotateY(roty);
		scale(scale);
		float translateY = (float) (currentFloorIndex * 50 - Math.pow(-1,
				currentFloorIndex)
				* 70
				* (MAX_CHANGE_FLOOR_COUNT - changeFloorCount)
				/ MAX_CHANGE_FLOOR_COUNT);

		translate(0, -translateY);
		hint(DISABLE_DEPTH_TEST);
		beginShape();
		transparent_floor1 = (float) (currentFloorIndex * 100 - Math.pow(-1,
				currentFloorIndex)
				* 160
				* (MAX_CHANGE_FLOOR_COUNT - changeFloorCount)
				/ MAX_CHANGE_FLOOR_COUNT);
		tint(255, transparent_floor1);
		texture(img_floor2);
		vertex(-FLOOR_WIDTH, 160, -FLOOR_WIDTH, 0, 0);
		vertex(FLOOR_WIDTH, 160, -FLOOR_WIDTH, img_floor2.width, 0);
		vertex(FLOOR_WIDTH, 160, FLOOR_WIDTH, img_floor2.width, img_floor2.height);
		vertex(-FLOOR_WIDTH, 160, FLOOR_WIDTH, 0, img_floor2.height);
		endShape();

		beginShape();
		transparent_floor2 = (float) ((3 - currentFloorIndex) * 100 - Math.pow(
				-1, 3 - currentFloorIndex)
				* 160
				/ MAX_CHANGE_FLOOR_COUNT
				* (MAX_CHANGE_FLOOR_COUNT - changeFloorCount));
		tint(255, transparent_floor2);
		texture(img_floor1);
		vertex(-FLOOR_WIDTH, 80, -FLOOR_WIDTH, 0, 0);
		vertex(FLOOR_WIDTH, 80, -FLOOR_WIDTH, img_floor1.width, 0);
		vertex(FLOOR_WIDTH, 80, FLOOR_WIDTH, img_floor1.width, img_floor1.height);
		vertex(-FLOOR_WIDTH, 80, FLOOR_WIDTH, 0, img_floor1.height);
		endShape();
		hint(ENABLE_DEPTH_TEST);
		colorMode(HSB, 360, 100, 100);
		if (currentFloorIndex == 1)
			img_temp = img_floor2;
		else {
			img_temp = img_floor1;
		}
		drawMountain(img_temp);
		fill(255, 30);
		pushMatrix();
		translate(0, 80);
		noStroke();
		hint(DISABLE_DEPTH_TEST);
		drawWall(2*FLOOR_WIDTH, 160, 2*FLOOR_WIDTH);
		hint(ENABLE_DEPTH_TEST);
		popMatrix();
		if (changeFloorCount > 0) {
			changeFloorCount--;
		}
	}

	public void drawMountain(PImage img_temp) {
		loadPixels();
		img_temp.loadPixels();

		for (int i = -FLOOR_WIDTH; i < FLOOR_WIDTH; i++)
			for (int j = -FLOOR_WIDTH; j < FLOOR_WIDTH; j++) {
				int x = (int) map(i, -FLOOR_WIDTH, FLOOR_WIDTH, 0, img_temp.width);
				int y = (int) map(j, -FLOOR_WIDTH, FLOOR_WIDTH, 0, img_temp.height);
				int location = x + y * img_temp.width;
				float hue = hue(img_temp.pixels[location]);
				float saturation = saturation(img_temp.pixels[location]);
				float brightness = brightness(img_temp.pixels[location]);
				float p_height =  map(saturation, 0, 100, 0, 20);
				// for wall.

				//float brightness2 = brightness(img_temp.pixels[location]);
				if (brightness < 10||saturation == 0) {
					
					/*
					hue = 10; 
					saturation = 10;
					brightness = 10;
					p_height = 1;
					stroke(hue, saturation, brightness, 20);
					
				} else {
				*/
					continue;
				}
				
				stroke(hue, saturation, brightness,
							120 - 2 * changeFloorCount);
				// stroke(hue,saturation,brightness,240-4*changeFloorCount);
				line(i, (3 - currentFloorIndex) * 80, j, i,
						(3 - currentFloorIndex) * 80 - p_height, j);
			}
	}

	public void drawWall(float w_width, float w_height, float w_length) {
		beginShape();
		vertex(-w_width / 2, w_height / 2, -w_length / 2);
		vertex(w_width / 2, w_height / 2, -w_length / 2);
		vertex(w_width / 2, -w_height / 2, -w_length / 2);
		vertex(-w_width / 2, -w_height / 2, -w_length / 2);
		endShape();
		beginShape();
		vertex(w_width / 2, w_height / 2, -w_length / 2);
		vertex(w_width / 2, w_height / 2, w_length / 2);
		vertex(w_width / 2, -w_height / 2, w_length / 2);
		vertex(w_width / 2, -w_height / 2, -w_length / 2);
		endShape();
		beginShape();
		vertex(w_width / 2, w_height / 2, w_length / 2);
		vertex(-w_width / 2, w_height / 2, w_length / 2);
		vertex(-w_width / 2, -w_height / 2, w_length / 2);
		vertex(w_width / 2, -w_height / 2, w_length / 2);
		endShape();
		beginShape();
		vertex(-w_width / 2, w_height / 2, w_length / 2);
		vertex(-w_width / 2, w_height / 2, -w_length / 2);
		vertex(-w_width / 2, -w_height / 2, -w_length / 2);
		vertex(-w_width / 2, -w_height / 2, w_length / 2);
		endShape();
	}

	public void mouseDragged() {
		float rate = (float) 0.01;
		rotx += (pmouseY - mouseY) * rate;
		roty += (mouseX - pmouseX) * rate;
	}

	public void keyPressed() {
		if (key == CODED) {
			if (keyCode == UP) {
				scale += 0.05;
			} else if (keyCode == DOWN) {
				scale -= 0.05;
			}
			scale = constrain(scale, (float) 0.8, (float) 2);
		}
		/*
		 * test change floor
		 */
		if (key == 'a') {
			if (currentFloorIndex == 2) {
				currentFloorIndex = 1;
				changeFloorCount = MAX_CHANGE_FLOOR_COUNT;
			}
		}
		if (key == 's') {
			if (currentFloorIndex == 1) {
				currentFloorIndex = 2;
				changeFloorCount = MAX_CHANGE_FLOOR_COUNT;
			}
		}
		if (key == 'd')
		{
			refreshImage();
		}
	}
	public void refreshImage()
	{
		img_floor1 = loadImage("./images/dst_floor1.png");
		img_floor2 = loadImage("./images/dst_floor0.png");
		changeFloorCount = MAX_CHANGE_FLOOR_COUNT/3;
	}
	/*
	public static void main(String args[]) {
		PApplet.main(new String[] { "--present", "Display3D" });
	}*/
}
